home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Utilities / Graphic / Conversion / viewers / GL Viewer 1.1.1 / src ƒ / gif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-04  |  17.3 KB  |  848 lines  |  [TEXT/KAHL]

  1. #ifndef lint
  2. static char rcs_id[] = "$Header:$";
  3. #endif  lint
  4.  
  5. #include <stdio.h>
  6. #include "glassert.h"
  7. #include "memoryio.h"
  8. #include "grasp.h"
  9.  
  10.  
  11. extern ImageStruct *readimage (FILE *fp, FilenameStruct *dirent, int filetype);
  12.  
  13.  
  14. #define INT_TYPE long
  15.  
  16.  
  17. #define FOPEN(filename, mode)            mopen (filename, mode)
  18. #define FCLOSE(stream)                mclose (stream)
  19. #define FSEEK(stream, offset, whence)        mseek (stream, offset, whence)
  20. #define FTELL(stream)                mtell (stream)
  21. #define FREAD(array, size, numitems, stream)    mread (array, size, numitems, stream)
  22. #define GETC(stream)                mgetc (stream)
  23. #define PUTC(c, stream)                mputc (c, stream)
  24.  
  25.  
  26. #define fatal(message)        error ("%s: %s\n", message)
  27.  
  28.  
  29. typedef int bool;
  30.  
  31. typedef struct codestruct
  32. {
  33.     struct codestruct *prefix;
  34.     unsigned char first,suffix;
  35.  
  36. } codetype;
  37.  
  38. static
  39. int datasize, codesize, codemask,
  40.     clear, eoi,
  41.     globalbits;
  42.  
  43. static
  44. unsigned int
  45.    *interleavetable = (unsigned int *) NULL;
  46.  
  47. static
  48. unsigned int
  49.     screenwidth,
  50.     screenheight,
  51.     xx,yy,
  52.     left,width,
  53.     top,height,
  54.     colorbits;
  55.  
  56. static
  57. bool
  58.     global,
  59.     interleaved;
  60.  
  61. static
  62. codetype
  63.     *codetable;
  64.  
  65. static
  66. char
  67.     colortable[256][3],
  68.     globalmap[256][3];
  69.  
  70. static
  71. unsigned int
  72.     rThresh;
  73. static
  74. unsigned int
  75.     rNormalize;
  76. static
  77. unsigned int
  78.     rColors;
  79. static
  80. float
  81.     rGamma;
  82.  
  83. #define RALL_COLORS    0
  84. #define RGRAYSCALE    1
  85. #define RRED        2
  86. #define RGREEN        3
  87. #define RBLUE        4
  88.  
  89. static
  90. int
  91.     red[256], green[256], blue[256];
  92.  
  93. static unsigned int  lastY = 0;
  94. static char        *pOut = (char *) NULL;
  95. static long         offsetP = 0L;
  96.  
  97. static MemoryFile   *tempfile = (MemoryFile *) NULL;
  98. static MemoryFile   *infile   = (MemoryFile *) NULL;
  99.  
  100.  
  101. #define PUTIPIXEL(x, y, val)                \
  102. {                            \
  103.     register unsigned int thisY = interleavetable[y];    \
  104.                             \
  105.     if (lastY != thisY)                    \
  106.     {                            \
  107.     register long delta;                \
  108.                             \
  109.     delta = (long) (width * (thisY - lastY - 1));    \
  110.     if (delta /* != 0L */)                \
  111.         FSEEK (tempfile, delta, 1);            \
  112.                             \
  113.     lastY = thisY;                    \
  114.     }                            \
  115.                             \
  116.     PUTC (val, tempfile);                \
  117. }
  118.  
  119. #define PUTPIXEL(x, y, val)    PUTC(val, tempfile)
  120.  
  121.  
  122.     void
  123. outcode (p)
  124.  
  125.    register codetype *p;
  126. {
  127.     int x, y;
  128.  
  129.  
  130.     assert (p);
  131.  
  132.     if (p->prefix)
  133.         outcode (p->prefix);
  134.  
  135.     if (interleaved)
  136.     {
  137.     PUTIPIXEL (xx, yy, p->suffix);
  138.     }
  139.     else
  140.     {
  141.     PUTPIXEL  (xx, yy, p->suffix);
  142.     }
  143.  
  144.     if (++xx > width - 1)
  145.     {
  146.         xx = 0;
  147.         yy++;
  148.  
  149.         if (yy > height - 1)
  150.             yy = 0;
  151.     }
  152. }
  153.  
  154.  
  155.     void
  156. process (code)
  157.  
  158.     register int code;
  159. {
  160.     static unsigned int avail = 0;
  161.     static int oldcode = 0;
  162.     register codetype *p;
  163.  
  164.  
  165.     if (code == clear) {
  166.         codesize = datasize + 1;
  167.         codemask = (1 << codesize) - 1;
  168.         avail = clear + 2;
  169.         oldcode = -1;
  170.     }
  171.     else if (code < avail) {
  172.         outcode(&codetable[code]);
  173.         if (oldcode != -1) {
  174.             p = &codetable[avail++];
  175.             p->prefix = &codetable[oldcode];
  176.             p->first = p->prefix->first;
  177.             p->suffix = codetable[code].first;
  178.             if ((avail & codemask) == 0 && avail < 4096L) {
  179.                 codesize++;
  180.                 codemask += avail;
  181.             }
  182.         }
  183.         oldcode = code;
  184.     } else if (code == avail && oldcode != -1) {
  185.         p = &codetable[avail++];
  186.         p->prefix = &codetable[oldcode];
  187.         p->first = p->prefix->first;
  188.         p->suffix = p->first;
  189.         outcode(p);
  190.         if ((avail & codemask) == 0 && avail < 4096L) {
  191.             codesize++;
  192.             codemask += avail;
  193.         }
  194.         oldcode = code;
  195.     } else {
  196.     char message[256];
  197.  
  198.     sprintf (message,
  199.          "Illegal code (0x%x > 0x%lx)) in raster data @ 0x%lx.",
  200.          code, avail, FTELL (infile) - 1L);
  201.     if (imverbose) {
  202.         sprintf (message + strlen (message),
  203.              "\n   Next pixel to write @ (%d, %d).\n", xx, yy);
  204.     }
  205.         fatal (message);
  206.     }
  207. }
  208.  
  209.  
  210.     void
  211. readraster (width, height)
  212.  
  213.     unsigned int width, height;
  214. {
  215.     unsigned char
  216.     buf[255];
  217.     register INT_TYPE bits=0;
  218.     register unsigned INT_TYPE count,datum=0;
  219.     register unsigned char *ch;
  220.     register unsigned int code;
  221.     register unsigned INT_TYPE readCount;
  222.  
  223.  
  224.     datasize = (unsigned int) GETC (infile);
  225.  
  226.     clear = 1 << datasize;
  227.     eoi      = clear+1;
  228.     codesize = datasize + 1;
  229.     codemask = (1 << codesize) - 1;
  230.  
  231.     codetable = (codetype *) malloc (4096L * (unsigned long) sizeof(codetype));
  232.     if (!codetable) fatal ("Not enough memory for code table");
  233.     for (code = 0; code < clear + 2; code++)
  234.     {
  235.         codetable[code].prefix = (codetype*)NULL;
  236.         codetable[code].first  = code;
  237.         codetable[code].suffix = code;
  238.     }
  239.     for (count = GETC (infile);
  240.          count > 0;
  241.          count = GETC (infile))
  242.     {
  243.         if ((readCount = (unsigned INT_TYPE) FREAD (buf, (size_t)1, (size_t) count, infile))
  244.             != count)
  245.         break;
  246.         for (ch=buf; count-- > 0; ch++) {
  247.             datum += (unsigned INT_TYPE) *ch << bits;
  248.             bits += 8;
  249.             while (bits >= codesize) {
  250.                 code = datum & codemask;
  251.                 datum >>= codesize;
  252.                 bits -= codesize;
  253.  
  254.                 if (code == eoi) goto exitloop;  /* This kludge put in
  255.                                                     because some GIF files
  256.                                                     aren't standard */
  257.                 process(code);
  258.             }
  259.         }
  260.     }
  261.  
  262.     {
  263.     char message[256];
  264.  
  265.     sprintf (message,
  266.          "Code block length %d had only %d bytes @ 0x%lx.",
  267.          count, readCount, FTELL (infile) - 1L);
  268.     if (imverbose) {
  269.         sprintf (message + strlen (message),
  270.              "\n   Next pixel to write @ (%d, %d).\n", xx, yy);
  271.     }
  272.     fatal (message);
  273.     }
  274.  
  275. exitloop:
  276.     if (imverbose &&
  277.     yy != height &&
  278.     xx != 0 && yy != 0)
  279.         fprintf (stderr,
  280.          "   Premature EOI code: next pixel @ (%d, %d).\n",
  281.          xx, yy);
  282.  
  283.     free (codetable);
  284. }
  285.  
  286.  
  287. /* Read image information (position, size, local color map, etc.). */
  288.  
  289.     static void
  290. myreadimage (void)
  291.  
  292. {
  293.     unsigned char
  294.         buf[9];
  295.  
  296.     bool
  297.         local;
  298.  
  299.     char
  300.         localmap[256][3];
  301.  
  302.     int localbits;
  303.  
  304.     register
  305.         row;
  306.  
  307.     register i;
  308.     void initcolors (char colortable[256][3], char colormap[256][3], int ncolors);
  309.  
  310.  
  311.     FSEEK (tempfile, 0L, 0);
  312.     lastY = 0L;
  313.  
  314.     FREAD (buf, (size_t)1, (size_t)9, infile);
  315.     left   = buf[0] + (buf[1] << 8);
  316.     top    = buf[2] + (buf[3] << 8);
  317.     width  = buf[4] + (buf[5] << 8);
  318.     height = buf[6] + (buf[7] << 8);
  319.     if (imverbose)
  320.     {
  321.     fprintf (stderr, "   Image origin at (%d, %d).\n", left, top);
  322.     fprintf (stderr, "   Image width and height are (%d, %d).\n",
  323.          width, height);
  324.     }
  325.  
  326.     if (tempfile /* != (MemoryFile *) NULL */)
  327.         (void) FCLOSE (tempfile);
  328.  
  329.     if ((tempfile = FOPEN ("raster", "wb")) == (MemoryFile *) NULL ||
  330.         FSEEK (tempfile, (size_t) width * (size_t) height - 1L, SEEK_CUR)
  331.             /* != 0 */)
  332.     {
  333.         (void) FCLOSE (tempfile);
  334.         (void) FCLOSE (infile);
  335.     error ("%s: not enough memory for raster image.\n", NULL);
  336.     return;
  337.     }
  338.  
  339.     (void) FSEEK (tempfile, 0L, SEEK_SET);
  340.  
  341.     local = buf[8] & 0x80;
  342.     interleaved = buf[8] & 0x40;
  343.     if (local)
  344.     {
  345.     long startMap = FTELL (infile);
  346.  
  347.         localbits = (buf[8] & 0x7) + 1;
  348.         FREAD(localmap, (size_t)3, (size_t)(1<<localbits), infile);
  349.     if (imverbose) {
  350.         fprintf (stderr,
  351.              "   Local color map (%d colors) from 0x%lx to 0x%lx.\n",
  352.              1 << localbits, startMap, FTELL (infile) - 1L);
  353.     }
  354.     colorbits = localbits;
  355.         initcolors(colortable, localmap, 1<<localbits);
  356.     } else if (global) {
  357.     colorbits = globalbits;
  358.         initcolors(colortable, (char **) globalmap, 1<<globalbits);
  359.     } else {
  360.         fatal ("No colormap present for image");
  361.     }
  362.     if (imverbose) {
  363.     fprintf (stderr, "   Image is %sinterleaved.\n",
  364.          interleaved ? "" : "not ");
  365.     }
  366.     if (interleaved)
  367.     {
  368.         interleavetable = (unsigned int *) malloc((unsigned long) (height * sizeof(int)));
  369.  
  370.         if (!interleavetable)
  371.             fatal ("Not enough memory for interleave table");
  372.         row = 0;
  373.         for (i = 0; i < height; i += 8)
  374.             interleavetable[row++] = i;
  375.         for (i = 4; i < height; i += 8)
  376.             interleavetable[row++] = i;
  377.         for (i = 2; i < height; i += 4)
  378.             interleavetable[row++] = i;
  379.         for (i = 1; i < height; i += 2)
  380.             interleavetable[row++] = i;
  381.     }
  382.  
  383.     readraster (width, height);
  384.  
  385.     if (interleavetable /* != (unsigned int *) NULL */)
  386.     {
  387.         free ((char *) interleavetable);
  388.         interleavetable = (unsigned int *) NULL;
  389.     }
  390. }
  391.  
  392.  
  393. /* Read a GIF extension block (and do nothing with it). */
  394.  
  395.     void
  396. readextension ()
  397.  
  398. {
  399.     unsigned char
  400.         code,
  401.         count;
  402.  
  403.     char
  404.         buf[255];
  405.  
  406.     code = GETC(infile);
  407.     while (count = GETC(infile))
  408.         FREAD (buf, (size_t)1,(size_t)count,infile);
  409. }
  410.  
  411.  
  412.     static int
  413. checksignature ()
  414.  
  415. {
  416.     char buf[6];
  417.     int     retVal = 0;
  418.  
  419.  
  420.     FREAD (buf, 1, 6, infile);
  421.  
  422.     if (strncmp (buf,"GIF",3))
  423.         retVal = -1;
  424.     if (strncmp (buf + 3,"87a",3))
  425.         retVal = -2;
  426.  
  427.     return retVal;
  428. }
  429.  
  430.  
  431.     static void
  432. readscreen (void)
  433.  
  434. {
  435.     unsigned char buf[7];
  436.  
  437.     xx = yy = 0;
  438.     FREAD (buf,1,7,infile);
  439.     screenwidth  = buf[0] + (buf[1] << 8);
  440.     screenheight = buf[2] + (buf[3] << 8);
  441.     if (imverbose) {
  442.     fprintf (stderr, "Screen width and height are (%d, %d).\n",
  443.          screenwidth, screenheight);
  444.     }
  445.  
  446.     global = buf[4] & 0x80;
  447.     if (global) {
  448.     long startGlobal = FTELL (infile);
  449.  
  450.         globalbits = (buf[4] & 0x07) + 1;
  451.         FREAD (globalmap, 3, 1 << globalbits, infile);
  452.  
  453.     if (imverbose) {
  454.         fprintf (stderr,
  455.              "Global color map (%d colors) from 0x%lx to 0x%lx.\n",
  456.              1 << globalbits, startGlobal, FTELL (infile) - 1L);
  457.     }
  458.     }
  459.     else {
  460.     if (imverbose) {
  461.         fprintf (stderr, "No global color map.\n");
  462.     }
  463.     }
  464. }
  465.  
  466.  
  467. #define MAX_INDEX(val)                        \
  468. {                                \
  469.     maxColor = (maxColor > (val)) ? maxColor : (val);        \
  470. }
  471.  
  472.  
  473. #define MAX_COLOR(r, g, b)                    \
  474. {                                \
  475.     MAX_INDEX (r);                        \
  476.     MAX_INDEX (g);                        \
  477.     MAX_INDEX (b);                        \
  478. }
  479.  
  480.  
  481. #define NORMALIZE_INDEX(val)                    \
  482. {                                \
  483.     (val) = ((val) * rNormalize + maxColor2) / maxColor;    \
  484.     if ((val) > 255)                        \
  485.         (val) = 255;                        \
  486. }
  487.  
  488.  
  489. #define NORMALIZE_COLOR(r, g, b)                \
  490. {                                \
  491.     NORMALIZE_INDEX (r);                    \
  492.     NORMALIZE_INDEX (g);                    \
  493.     NORMALIZE_INDEX (b);                    \
  494. }
  495.  
  496.  
  497. #define GRAYSCALE_COLOR(r, g, b)                \
  498. {                                \
  499.     register int lum = 299 * (r) + 587 * (g) + 114 * (b);    \
  500.     register int grayvalue = (lum + 500) / 1000;        \
  501.                                 \
  502.     if (grayvalue > 255)                    \
  503.         grayvalue = 255;                    \
  504.                                 \
  505.     (r) = grayvalue;                        \
  506.     (g) = grayvalue;                        \
  507.     (b) = grayvalue;                        \
  508. }
  509.  
  510.  
  511. #define GAMMA_INDEX(val)                    \
  512. {                                \
  513.     (val) = gamma[(val)];                    \
  514. }
  515.  
  516.  
  517. #define GAMMA_CORRECT(r, g, b)                    \
  518. {                                \
  519.     GAMMA_INDEX (r);                        \
  520.     GAMMA_INDEX (g);                        \
  521.     GAMMA_INDEX (b);                        \
  522. }
  523.  
  524.  
  525.     static void
  526. process_loop (void)
  527.  
  528. {
  529.     int quit        = FALSE;
  530.     int imageNum    = 0;
  531.     long startImage = 0L;
  532.  
  533.  
  534.     do
  535.     {
  536.     unsigned char ch;
  537.  
  538.  
  539.         ch = (unsigned char) GETC (infile);
  540.  
  541.         switch (ch)
  542.         {
  543.             case '\0':  if (imverbose)
  544.                     {
  545.                 fprintf (stderr,
  546.                      "   EOD encountered @ 0x%lx.\n",
  547.                      FTELL (infile) - 1L);
  548.             }
  549.                 break;  /* this kludge for non-standard files */
  550.  
  551.             case ',':   startImage = FTELL (infile) - 1L;
  552.                 if (imverbose)
  553.                 {
  554.                 fprintf (stderr,
  555.                      ":::Processing image %d @ 0x%lx.\n",
  556.                      imageNum + 1, startImage);
  557.             }
  558.                         myreadimage ();
  559.                         break;
  560.  
  561.             case ';':   quit = TRUE;
  562.                 if (imverbose)
  563.                 {
  564.                 long currPos = FTELL (infile) - 1L;
  565.                 long diffPos;
  566.  
  567.                 if (imverbose)
  568.                     fprintf (stderr,
  569.                      ":::GIF terminator @ 0x%lx.\n",
  570.                      currPos);
  571.  
  572.                 FSEEK (infile, 0L, 2);
  573.                 if ((diffPos = FTELL (infile) - 1L - currPos) > 1L)
  574.                 {
  575.                 if (imverbose)
  576.                     fprintf (stderr,
  577.                          ":::%ld trailing extra bytes.\n",
  578.                          diffPos);
  579.                 }
  580.             }
  581.                         break;
  582.  
  583.             case '!':    if (imverbose)
  584.                     {
  585.                 fprintf (stderr,
  586.                      ":::Skipping extension @ 0x%lx.\n",
  587.                      FTELL (infile) - 1L);
  588.             }
  589.                 readextension ();
  590.                         break;
  591.  
  592.             default: {
  593.             char message[80];
  594.  
  595.             sprintf (message,
  596.                  "Illegal GIF block type (0x%x) @ 0x%lx.",
  597.                  ch, FTELL (infile) - 1L);
  598.                         fatal (message);
  599.                         break;
  600.              }
  601.         }
  602.     } while (!quit);
  603. }
  604.  
  605.  
  606.     static void
  607. initcolors (colortable, colormap, ncolors)
  608.  
  609.     char colortable[256][3];
  610.     char colormap[256][3];
  611.     int ncolors;
  612. {
  613.     register
  614.         i;
  615.     char
  616.         isColor = 0;
  617.     int
  618.         maxColor = 0;
  619.  
  620.     /*...Determine if image is grayscale; also, find maximum intensity...*/
  621.  
  622.     for (i = 0; i < ncolors; i++) {
  623.         red[i]   = colormap[i][0];
  624.         green[i] = colormap[i][1];
  625.         blue[i]  = colormap[i][2];
  626.  
  627.     colortable[i][0] = colormap[i][0];
  628.     colortable[i][1] = colormap[i][1];
  629.     colortable[i][2] = colormap[i][2];
  630.  
  631.     if (rColors == RGRAYSCALE || imverbose)
  632.         isColor |= ((red[i]  != green[i]) ||
  633.             (red[i]  != blue[i])  ||
  634.             (blue[i] != green[i]    ));
  635.  
  636.     if (rNormalize /* != 0 */ || imverbose)
  637.     {
  638.         MAX_COLOR (red[i], green[i], blue[i]);
  639.     }
  640.     }
  641.  
  642.     /*...Convert from color to grayscale using NTSC algorithm...*/
  643.  
  644.     if (rColors == RGRAYSCALE)
  645.     {
  646.     if (isColor)
  647.     {
  648.         if (imverbose)
  649.         fprintf (stderr, "   Grayscaling color table.\n");
  650.  
  651.         maxColor = 0;
  652.  
  653.         for (i = 0; i < ncolors; i++)
  654.         {
  655.         GRAYSCALE_COLOR (red[i], green[i], blue[i]);
  656.  
  657.         if (rNormalize /* != 0 */ || imverbose)
  658.         {
  659.             MAX_INDEX (red[i]);
  660.         }
  661.         }
  662.     }
  663.     else
  664.     {
  665.         fprintf (stderr,
  666.              "   \"-g\" ignored: image is already grayscale.\n");
  667.     }
  668.     }
  669.  
  670.     /*...Re-scale the intensities...*/
  671.  
  672.     if (rNormalize /* != 0 */ && maxColor /* != 0 */)
  673.     {
  674.     if (rNormalize != maxColor)
  675.     {
  676.         int maxColor2 = maxColor >> 1;
  677.  
  678.         if (imverbose)
  679.             fprintf (stderr,
  680.              "   Normalizing maximum color value from %d to %d.\n",
  681.              maxColor, rNormalize);
  682.  
  683.         for (i = 0; i < ncolors; i++)
  684.         {
  685.         NORMALIZE_COLOR (red[i], green[i], blue[i]);
  686.         }
  687.     }
  688.     else
  689.     {
  690.         if (imverbose)
  691.             fprintf (stderr, "   Maximum is normalization.\n");
  692.     }
  693.     }
  694.  
  695.     /*...Gamma correct the intensities...*/
  696.  
  697.     if (rGamma > 0.0)
  698.     {
  699.     int    gamma[256];
  700.     double gammaInv = (double) (1.0 / rGamma);
  701.  
  702.     if (imverbose)
  703.         fprintf (stderr,
  704.              "   Adjusting color table with gamma %f.\n",
  705.              rGamma);
  706.  
  707.     for (i = 0; i < 256; i++)
  708.     {
  709.         double pow ();
  710.  
  711.         gamma[i] = (int) (255.0 * pow ((double) ((float) i / 255.0),
  712.                        gammaInv)
  713.                   + 0.5);
  714.     }
  715.  
  716.     for (i = 0; i < ncolors; i++)
  717.     {
  718.         GAMMA_CORRECT (red[i], green[i], blue[i]);
  719.     }
  720.     }
  721.  
  722.     if (imverbose)
  723.         fprintf (stderr,
  724.          "   Image is %s with maximum single channel intensity %d.\n",
  725.          isColor ? "color" : "grayscale", maxColor);
  726. }
  727.  
  728.  
  729.     ImageStruct *
  730. readgifimage (fp, dirent)
  731.  
  732.     FILE       *fp;
  733.     FilenameStruct *dirent;
  734. {
  735.     ImageStruct *im = (ImageStruct *) NULL;
  736.     XImage      *xim;
  737.     long         filesize;
  738.  
  739.  
  740.     im = (ImageStruct *) malloc ((size_t) sizeof (ImageStruct));
  741.     assert (im);
  742.  
  743.     fseek (fp, dirent->offset, 0);
  744.  
  745.     filesize = GetLong (fp);    /* length of whole image file... */
  746.  
  747.     im->name = strtok (strdup (dirent->fname), ".");
  748.     im->type = EXT_GIF;
  749.     im->xoff = 0;
  750.     im->yoff = 0;
  751.  
  752.     if ((infile = FOPEN (im->name, "rb")) == (MemoryFile *) NULL ||
  753.         FSEEK (infile, filesize - 1L, SEEK_SET) /* != 0 */)
  754.     {
  755.         (void) FCLOSE (infile);
  756.     error("%s: not enough memory to read gif file.\n", NULL);
  757.     goto premature_exit;
  758.     }
  759.  
  760.     if (fread (infile->buffer, filesize, 1, fp) != 1)
  761.     {
  762.         (void) FCLOSE (infile);
  763.     error("%s: GIF data read failed\n", NULL);
  764.     goto premature_exit;
  765.     }
  766.  
  767.     (void) FSEEK (infile, 0L, SEEK_SET);
  768.  
  769.     if (checksignature () /* != 0 */)
  770.     {
  771.         (void) FCLOSE (infile);
  772.     free (im->name);
  773.     free ((char *) im);
  774.     return (ImageStruct *) readimage (fp, dirent, EXT_PIC);
  775.     }
  776.  
  777.     readscreen ();
  778.  
  779.     /*...Define global colormap...*/
  780.  
  781.     if (global)
  782.     {
  783.     unsigned long    pmasks;
  784.     u_long        pixels[256];
  785.     short        i;
  786.  
  787.  
  788.     im->cmaplen = 1 << globalbits;
  789.  
  790.      im->cmap = XCreateColormap (dsp, win, vis, AllocNone);
  791.      XAllocColorCells (dsp, im->cmap, True, (unsigned long *) &pmasks,
  792.                       0, (unsigned long *) pixels, im->cmaplen);
  793.     for (i = 0; i < im->cmaplen; i++)
  794.     {
  795.         im->colors[i].pixel = pixels[i];
  796.         im->colors[i].red   = globalmap[i][0] << 8;
  797.         im->colors[i].green = globalmap[i][1] << 8;
  798.         im->colors[i].blue  = globalmap[i][2] << 8;
  799.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  800.  
  801.         if (imverbose) {
  802.         printf("%02x%02x%02x ",
  803.                im->colors[i].red >> 8,
  804.                im->colors[i].green >> 8,
  805.                im->colors[i].blue >> 8);
  806.         if (!((i + 1) % 8))
  807.             printf("\n");
  808.         }
  809.     }
  810.  
  811.     XStoreColors (dsp, im->cmap, im->colors, im->cmaplen);
  812.     }
  813.     else
  814.     {
  815.     im->cmap    = (Colormap) NULL;
  816.     im->cmaplen = 0;
  817.     }
  818.  
  819.     process_loop ();
  820.  
  821.     (void) FCLOSE (infile);
  822.  
  823.     im->w = width;
  824.     im->h = height;
  825.     im->d = 8;
  826.  
  827.     xim = XCreateImage (dsp, vis, im->d, ZPixmap, 0, tempfile->buffer,
  828.                im->w, im->h, 8, im->w);
  829.     tempfile->buffer = (char *) NULL;
  830.  
  831. #if 0
  832.     im->pix = XCreatePixmap(dsp, win, im->w, im->h, 8);
  833.     XPutImage(dsp, im->pix, gc, xim, 0, 0, 0, 0, im->w, im->h);
  834.     XSync(dsp, False);
  835. #endif
  836.  
  837.     im->w   = xim->width;
  838.     im->h   = xim->height;
  839.     im->pix = (Pixmap) xim;
  840.  
  841.     (void) FCLOSE (tempfile);
  842.     tempfile = (MemoryFile *) NULL;
  843.  
  844. premature_exit:
  845.  
  846.     return im;
  847. }
  848.